package com.qdxwx.data.service.user;

import com.qdxwx.common.exception.AccountException;
import com.qdxwx.common.page.PageRequest;
import com.qdxwx.common.utils.ObjectUtils;
import com.qdxwx.common.utils.TKConvert;
import com.qdxwx.common.utils.TKRequest;
import com.qdxwx.data.mapper.user.UserInviteMapper;
import com.qdxwx.data.mapper.user.UserMapper;
import com.qdxwx.data.service.account.UserAccountService;
import com.qdxwx.data.service.company.CompanyAccountService;
import com.qdxwx.data.service.company.CompanyService;
import com.qdxwx.data.service.course.CourseService;
import com.qdxwx.data.service.order.OrderAllotDetailService;
import com.qdxwx.data.service.order.OrderDetailService;
import com.qdxwx.data.service.teacher.TeacherService;
import com.qdxwx.data.service.website.WebsiteProfileService;
import com.qdxwx.models.account.UserAccount;
import com.qdxwx.models.company.Company;
import com.qdxwx.models.course.Course;
import com.qdxwx.models.enums.*;
import com.qdxwx.models.order.Order;
import com.qdxwx.models.order.OrderDetail;
import com.qdxwx.models.teacher.Teacher;
import com.qdxwx.models.user.User;
import com.qdxwx.models.user.UserInvite;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * Qdx NetSchool Platform
 * @author qdxwx
 * @updateTime 2022/5/25
 * @description
 */
@Service
public class UserInviteServiceImpl implements UserInviteService {
    @Autowired
    private UserInviteMapper userInviteMapper;
    @Autowired
    private WebsiteProfileService websiteProfileService;
    @Autowired
    private UserAccountService userAccountService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private CourseService courseService;
    @Autowired
    private CompanyAccountService companyAccountService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private OrderAllotDetailService orderAllotDetailService;

    /**
     * 添加qdx_user_invites
     */
    @Override
    public int add(UserInvite userInvite) throws AccountException {
        userInvite.setAddTime(LocalDateTime.now());
        return userInviteMapper.insert(userInvite);
    }

    /**
     * 通过id，查询qdx_user_invites
     */
    @Override
    public UserInvite get(long id) {
        if (id < 1) return null;
        return userInviteMapper.selectById(id);
    }

    @Override
    public UserInvite getByInviteUserId(long userId) {
        if (userId < 1) return null;
        return userInviteMapper.selectByInviteUserId(userId);
    }


    @Override
    public List<UserInvite> getList(UserInvite userInvite, PageRequest page) {
        return userInviteMapper.selectList(userInvite, page);
    }

    @Override
    public long count(UserInvite userInvite) {
        return userInviteMapper.count(userInvite);
    }


    @Override
    public void orderCashback(HttpServletRequest request, Order order) throws AccountException {
        //分销配置 , 根据返现配置返现
        Map<String, Object> invite = websiteProfileService.getMap(WebsiteProfileType.invite.toString());
        if ("ON".equals(invite.get("enabled"))) {
            int rateCourse = TKConvert.toInteger(invite.get("rateCourse"));
            int rateLive = TKConvert.toInteger(invite.get("rateLive"));
            int ratePartner = TKConvert.toInteger(invite.get("ratePartner"));
            int rateSeller = TKConvert.toInteger(invite.get("rateSeller"));
            int rateAgent = TKConvert.toInteger(invite.get("rateAgent"));
            int rateMember = TKConvert.toInteger(invite.get("rateMember"));
            int backMoney;
            int backRate;
            String description;

            //查询用户是否是被邀请的，先从Session里获取
            UserInvite userInvite = getSession(request);
            if (ObjectUtils.isNull(userInvite)) {
                //没有Session再到数据里去查询
                userInvite = getByInviteUserId(order.getUserId());
            }

            if (ObjectUtils.isNotNull(userInvite)) {
                //这里是给宣传的销售者返现
                backRate = rateSeller;
                if (OrderType.MEMBER.equals(order.getOrderType())) {
                    backRate = rateMember;//如果是会员订单，给会员比例
                }
                description = "分享销售返现（orderId:" + order.getOrderId() + ";" + backRate + "%)";
                backMoney = order.getPayAmount() * backRate / 100;
                //金额大于 0 才返
                if (backMoney > 0) {
                    // userAccount要重新查询一次，否则乐观锁版本号异常
                    UserAccount userAccount = userAccountService.getByUserId(userInvite.getUserId());
                    userAccountService.income(userAccount, backMoney, AccountType.BACK, AccountHistoryType.BACKMONEY, order.getOrderId(), description, true, AccountBizType.ADMIN);
                    //分成记录
                    orderAllotDetailService.create(order, userMapper.selectById(userInvite.getUserId()), backRate, backMoney, description);
                    //假如有上级的情况下，再上级拿rateAgent
                    UserInvite parentInvite = getByInviteUserId(userInvite.getUserId());
                    if (ObjectUtils.isNotNull(parentInvite)) {
                        backRate = rateAgent;
                        description = "下级分享返现（orderId:" + order.getOrderId() + ";" + backRate + "%)";
                        backMoney = order.getPayAmount() * backRate / 100;
                        //金额大于 0 才返
                        if (backMoney > 0) {
                            // userAccount要重新查询一次，否则乐观锁版本号异常
                            userAccount = userAccountService.getByUserId(parentInvite.getUserId());
                            userAccountService.income(userAccount, backMoney, AccountType.BACK, AccountHistoryType.BACKMONEY, order.getOrderId(), description, true, AccountBizType.ADMIN);
                            //分成记录
                            orderAllotDetailService.create(order, userMapper.selectById(parentInvite.getUserId()), backRate, backMoney, description);
                        }
                    }
                }
            }
            //Company company = companyService.get(order.getCompanyId());
            //if (company == null) {
            //    company = new Company();
            //    company.setCompanyId(0);
            //    company.setParentId(0);
            //}
            //平台分成（或组织者）
            if (order.getCompanyId() > 1) {
                Company company = companyService.get(order.getCompanyId());
                if (company != null) {
                    backRate = ratePartner;
                    description = "平台销售分成(" + backRate + "%)";
                    //如果已有分销的，说明不是直接销售，合伙人拿代理提成
                    if (ObjectUtils.isNotNull(userInvite)) {
                        backRate = rateAgent;
                        description = "平台分享分成(" + backRate + "%)";
                    }
                    backMoney = order.getPayAmount() * backRate / 100;
                    if (backMoney > 0) {
                        companyAccountService.income(order.getCompanyId(), backMoney
                                , order.getOrderId(), description, OrderType.COURSE.equals(order.getOrderType()) ? AccountBizType.COURSE : AccountBizType.MEMBER
                        );
                        //分成记录
                        orderAllotDetailService.create(order, company, backRate, backMoney, description);
                    }

                    //直接销售且机构Id大于1的，父级机构享受代理分成
                    if (company.getParentId() > 1 && ObjectUtils.isNull(userInvite)) {
                        backRate = rateAgent;
                        description = "合伙人销售分成(" + backRate + "%)";
                        backMoney = order.getPayAmount() * backRate / 100;
                        if (backMoney > 0) {
                            companyAccountService.income(company.getParentId(), backMoney
                                    , order.getOrderId(), description, OrderType.COURSE.equals(order.getOrderType()) ? AccountBizType.COURSE : AccountBizType.MEMBER
                            );
                            //分成记录
                            orderAllotDetailService.create(order, companyService.get(company.getParentId()), backRate, backMoney, description);
                        }
                    }
                }
            }
            //首先是创作者分成，只有课程才有创作者分成
            if (OrderType.COURSE.equals(order.getOrderType())) {
                List<OrderDetail> details = orderDetailService.getListByOrderId(order.getOrderId());
                for (OrderDetail detail : details) {
                    Course course = courseService.get(detail.getCourseId());
                    if (course != null && course.getUserId() > 0) {
                        //backMoney += (课程价格/订单金额)*实际扣除金额 * 返现比例
                        //此计算公式实现使用优惠后，按比例分摊优惠
                        //按比例分摊优惠，重新设置价格
                        detail.setPrice((detail.getPrice() / order.getOrderAmount()) * order.getPayAmount());

                        backRate = rateCourse;
                        if ("LIVE".equals(course.getSellType())) {
                            backRate = rateLive;
                        }
                        description = "课程销售分成(courseId:" + detail.getCourseId() + ";" + backRate + "%)";
                        backMoney = detail.getPrice() * backRate / 100;
                        //金额大于 0 才返
                        if (backMoney > 0) {
                            // userAccount要重新查询一次，否则乐观锁版本号异常
                            UserAccount userAccount = userAccountService.getByUserId(course.getUserId());
                            userAccountService.income(userAccount, backMoney, AccountType.BACK, AccountHistoryType.BACKMONEY, order.getOrderId(),
                                    description, true, AccountBizType.ADMIN);
                            //分成记录
                            orderAllotDetailService.create(detail, userMapper.selectById(course.getUserId()), backRate, backMoney, description);
                        }
                        if (order.getCompanyId() <= 1) {
                            //没有享受平台分成时，查找教师所属机构，机构大于1享受合伙人分成
                            Teacher teacher = teacherService.getByUserId(course.getUserId());
                            if (teacher != null && teacher.getCompanyId() != null && teacher.getCompanyId() > 1) {
                                //backMoney += (课程价格/订单金额)*实际扣除金额 * 返现比例
                                //此计算公式实现使用优惠后，按比例分摊优惠
                                backRate = ratePartner;
                                description = "课程销售分成";
                                //如果已有分销的，说明不是直接销售，合伙人拿代理分成
                                if (ObjectUtils.isNotNull(userInvite)) {
                                    backRate = rateAgent;
                                    description = "课程代理分成";
                                }
                                description += "(" + teacher.getName() + "[" + teacher.getId() + "];courseId:" + course.getCourseId() + ";" + backRate + "%)";
                                backMoney = detail.getPrice() * backRate / 100;
                                if (backMoney > 0) {
                                    companyAccountService.income(teacher.getCompanyId(), backMoney
                                            , order.getOrderId(), description, AccountBizType.COURSE);
                                    //分成记录
                                    orderAllotDetailService.create(detail, companyService.get(teacher.getCompanyId()), backRate, backMoney, description);

                                }
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public void finishReg(User user, HttpServletRequest request) {
        if (user == null) return;
        UserInvite userInvite = getSession(request);
        if (userInvite == null) return;
        if (userInvite.getUserId() == user.getUserId()) {
            //分享人和下线不能是同一人
            System.out.printf("userId(%s)inviteUserId(%s)", userInvite.getUserId(), user.getUserId());
            return;
        }
        System.out.println("userInvite:" + userInvite);
        userInvite.setInviteUserId(user.getUserId());
        userInvite.setInviteUserName(user.getUserName());
        //分销配置
        Map<String, Object> invite = websiteProfileService.getMap(WebsiteProfileType.invite.toString());
        int regCashback = TKConvert.toInteger(invite.get("regCashback"));
        userInvite.setCashback(regCashback);

        int count = add(userInvite);

        if (regCashback > 0 && count > 0) {
            UserAccount userAccount = userAccountService.getByUserId(userInvite.getUserId());
            //给邀请人返现充值
            userAccountService.income(userAccount, regCashback, AccountType.BACK, AccountHistoryType.BACKMONEY, 0, "邀请注册返现", true, AccountBizType.ADMIN);
        }
    }

    @Override
    public void setSession(HttpServletRequest request) {
        //这里传入的是用户Id
        long inviteId = TKConvert.toLong(request.getParameter("uid"));
        if (inviteId > 0) {
            if (inviteId < 1000) {
                inviteId = inviteId + 1000;
            }
            HttpSession session = request.getSession();
            if (session.getAttribute("invite_uid") == null || TKConvert.toLong(session.getAttribute("invite_uid")) < 1) {
                //没用邀请码的不需要创建
                session.setAttribute("invite_uid", inviteId);//丢进session里
            }
        }
    }

    @Override
    public UserInvite getSession(HttpServletRequest request) {
        HttpSession session = request.getSession();
        if (session.getAttribute("invite_uid") == null) {
            //没用邀请码的不需要创建
            return null;
        }
        long userId = TKConvert.toLong(session.getAttribute("invite_uid"));
        if (userId < 1) return null;
        UserInvite ret = new UserInvite();
        ret.setUserId(userId);
        if (TKRequest.isWxBrowse(request)) {
            ret.setRegisterFrom("WEIXIN");
        } else if (TKRequest.isMobileBrowse(request)) {
            ret.setRegisterFrom("MOBILE");
        } else {
            ret.setRegisterFrom("WEB");
        }
        session.removeAttribute("invite_uid");
        return ret;
    }

    @Override
    public int updateCombine(long userId1, long userId2) {
        if(userId1 < 1 || userId2 < 1){
            throw new RuntimeException("更新用户邀请：参数错误");
        }
        return userInviteMapper.updateCombine(userId1, userId2);
    }
}



